package com.joker.demo.core.scheduler;


import com.joker.demo.core.config.JobSchedulerProperties;
import com.joker.demo.core.domain.dto.TaskExecuteRequestDTO;
import com.joker.demo.core.domain.dto.TaskExecuteResponseDTO;
import com.joker.demo.core.domain.enums.JobRunStatusEnum;
import com.joker.demo.core.exception.BizException;
import com.joker.demo.core.executor.smart.TaskExecutionManager;
import com.joker.demo.core.netty.server.NettyServer;
import com.joker.demo.core.netty.server.handler.NettyServerHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 调度器帮助类
 * 提供统一的调度器初始化和管理功能
 *
 * @author : feixiang.li
 * @since : 2025-07-24 20:21
 */
public class JobScheduler implements ApplicationContextAware, SmartInitializingSingleton, DisposableBean {


    private static final Logger log = LoggerFactory.getLogger(JobScheduler.class);

    /**
     * 调度器配置
     */
    private final JobSchedulerProperties properties;

    /**
     * Netty服务器
     */
    private NettyServer nettyServer;

    /**
     * 调度器服务
     */
    private ApplicationContext applicationContext;


    /**
     * 调度器服务
     */
    private JobSchedulerHandlerService jobSchedulerHandlerService;

    /**
     * 任务执行管理器
     */
    private TaskExecutionManager taskExecutionManager;

    /**
     * 是否已初始化
     */
    private boolean initialized = false;


    @Override
    public void destroy() throws Exception {
        log.info("任务执行器销毁");
        stop();
    }

    /**
     * 启动调度器-Bean已经初始化完成
     */
    @Override
    public void afterSingletonsInstantiated() {
        if (initialized) {
            log.warn("调度器已经初始化，跳过重复初始化");
            return;
        }
        try {
            // 初始化调度器服务
            jobSchedulerHandlerService = applicationContext.getBean(JobSchedulerHandlerService.class);
            // 获取相关配置
            log.info("相关配置信息: {}", properties);
            // 初始化任务执行管理器
            taskExecutionManager = new TaskExecutionManager(null);
            // 启动Netty服务器
            startNettyServer();
            initialized = true;
            log.info("springboot调度中心启动完成");
        } catch (Exception e) {
            throw new BizException("初始化调度器失败", e);
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        log.info("注入spring上下文:{}", applicationContext);
    }

    /**
     * 普通Java项目初始化
     *
     * @param jobSchedulerPropertiesInit 配置文件路径
     */
    public JobScheduler(JobSchedulerProperties jobSchedulerPropertiesInit) {
        this.properties = jobSchedulerPropertiesInit;
        log.info("相关配置信息: {}", properties);
    }


    /**
     * 启动Netty服务器
     */
    private void startNettyServer() {
        log.info("启动Netty服务器");

        try {
            // 创建Netty服务器处理器
            NettyServerHandler serverHandler = new NettyServerHandler(jobSchedulerHandlerService);
            // 创建Netty服务器
            nettyServer = new NettyServer(serverHandler, properties);
            nettyServer.connect();
            log.info("Netty服务器启动成功，端口: {}", properties.getPort());
        } catch (Exception e) {
            throw new BizException("启动Netty服务器失败", e);
        }
    }


    /**
     * 发送任务执行请求
     *
     * @param taskExecuteResponse 任务执行响应
     */
    public void sendExecuteTask(TaskExecuteRequestDTO taskExecuteResponse) {
        if (!initialized) {
            throw new BizException("【调度器】未初始化");
        }
        log.info("【调度器】发送任务执行请求: {}", taskExecuteResponse);
        taskExecutionManager.getTaskExecutor().submit(() -> jobSchedulerHandlerService.sendExecuteTask(taskExecuteResponse));
    }

    /**
     * 发送任务取消请求
     *
     * @param taskExecuteResponse 任务执行响应
     */
    public void sendCancelTask(TaskExecuteResponseDTO taskExecuteResponse) {
        if (!initialized) {
            throw new BizException("调度器未初始化");
        }

        log.info("【调度器】发送任务取消请求: {}", taskExecuteResponse);

        // 使用任务执行管理器异步处理
        taskExecutionManager.getTaskExecutor().submit(() -> jobSchedulerHandlerService.sendCancelTask(taskExecuteResponse));
    }

    /**
     * 处理任务执行响应
     *
     * @param taskExecuteResponse 处理任务执行响应
     */
    public void handleExecuteTaskResponse(TaskExecuteResponseDTO taskExecuteResponse) {
        log.info("处理任务执行响应: {}", taskExecuteResponse);

        try {
            // 执行器-> 调度器 发送取消任务的响应请求，说明自己取消成功或者取消失败
            if (JobRunStatusEnum.CANCELED.getCode().equals(taskExecuteResponse.getStatus())) {
                jobSchedulerHandlerService.cancel(taskExecuteResponse);
                log.info("任务开始运行: {}", taskExecuteResponse.getJobId());
            } else {
                // TODO:发送告警信息
            }
        } catch (Exception e) {
            log.error("处理任务执行响应失败: {}", taskExecuteResponse.getJobId(), e);
        }
    }

    /**
     * 处理任务结果
     */
    public void handleTaskResult(TaskExecuteResponseDTO taskExecuteResponse) {
        log.info("处理任务结果: {}", taskExecuteResponse);
        jobSchedulerHandlerService.receiveExecuteTaskResponse(taskExecuteResponse);
    }

    /**
     * 处理任务取消响应
     */
    public void handleCancelTaskResponse(TaskExecuteResponseDTO taskExecuteResponse) {
        log.info("处理任务取消响应: {}", taskExecuteResponse);
        jobSchedulerHandlerService.receiveExecuteTaskResponse(taskExecuteResponse);
    }


    /**
     * 启动调度器
     */
    public void start() {
        if (!initialized) {
            throw new RuntimeException("调度器未初始化，请先调用构造函数进行初始化");
        }

        log.info("调度器已启动，监听端口: {}", properties.getPort());
    }

    /**
     * 停止调度器
     */
    public void stop() {
        if (!initialized) {
            log.warn("调度器未初始化，无需停止");
            return;
        }

        log.info("停止调度器");

        try {
            // 关闭任务执行管理器
            if (taskExecutionManager != null) {
                taskExecutionManager.shutdown();
                log.info("任务执行管理器已关闭");
            }

            // 关闭Netty服务器
            if (nettyServer != null) {
                nettyServer.stop();
                log.info("Netty服务器已关闭");
            }

            initialized = false;
            log.info("调度器已停止");

        } catch (Exception e) {
            log.error("停止调度器时发生异常", e);
        }
    }

    /**
     * 获取调度器服务
     */
    public JobSchedulerHandlerService getJobSchedulerHandlerService() {
        return jobSchedulerHandlerService;
    }


    public NettyServer getNettyServer() {
        return nettyServer;
    }

    /**
     * 检查是否已初始化
     */
    public boolean isInitialized() {
        return initialized;
    }

    /**
     * 检查连接状态
     */
    public boolean isConnected() {
        return nettyServer != null;
    }

    /**
     * 获取任务执行管理器
     */
    public TaskExecutionManager getTaskExecutionManager() {
        return taskExecutionManager;
    }


    /**
     * 获取线程池状态
     */
    public TaskExecutionManager.ThreadPoolStatus getThreadPoolStatus() {
        if (taskExecutionManager == null) {
            return null;
        }
        return taskExecutionManager.getThreadPoolStatus();
    }

    /**
     * 获取连接的客户端数量
     */
    public int getConnectedClientsCount() {
        // 简化实现，返回0
        return 0;
    }

    /**
     * 获取客户端连接信息
     */
    public Map<String, Object> getClientConnections() {
        // 简化实现，返回空Map
        return new ConcurrentHashMap<>();
    }


}
